home *** CD-ROM | disk | FTP | other *** search
/ User's Choice Windows CD / User's Choice Windows CD (CMS Software)(1993).iso / win_u_z / xlock_dv.zip / SOURCES.ZIP / XLOCK.C < prev    next >
C/C++ Source or Header  |  1992-09-08  |  20KB  |  772 lines

  1. #ifndef lint
  2. static char sccsid[] = "@(#)xlock.c 22.3 89/09/20";
  3. #endif
  4. /*-
  5.  * xlock.c - X11 client to lock a display and show a screen saver.
  6.  *
  7.  * Copyright (c) 1988-89 by Patrick Naughton and Sun Microsystems, Inc.
  8.  *
  9.  * Permission to use, copy, modify, and distribute this software and its
  10.  * documentation for any purpose and without fee is hereby granted,
  11.  * provided that the above copyright notice appear in all copies and that
  12.  * both that copyright notice and this permission notice appear in
  13.  * supporting documentation.
  14.  *
  15.  * This file is provided AS IS with no warranties of any kind.  The author
  16.  * shall have no liability with respect to the infringement of copyrights,
  17.  * trade secrets or any patents by this file or any part thereof.  In no
  18.  * event will the author be liable for any lost revenue or profits or
  19.  * other special, indirect and consequential damages.
  20.  *
  21.  * Comments and additions should be sent to the author:
  22.  *
  23.  *               naughton@sun.com
  24.  *
  25.  *               Patrick J. Naughton
  26.  *               Window Systems Group, MS 14-40
  27.  *               Sun Microsystems, Inc.
  28.  *               2550 Garcia Ave
  29.  *               Mountain View, CA  94043
  30.  *
  31.  * Revision History:
  32.  * 20-Sep-89: Linted and made -saver mode grab the keyboard and mouse.
  33.  *          Replaced SunView code for life mode with Jim Graham's version,
  34.  *        so I could contrib it without legal problems.
  35.  *          Sent to expo for X11R4 contrib.
  36.  * 19-Sep-89: Added '?'s on input.
  37.  * 27-Mar-89: Added -qix mode.
  38.  *          Fixed GContext->GC.
  39.  * 20-Mar-89: Added backup font (fixed) if XQueryLoadFont() fails.
  40.  *          Changed default font to lucida-sans-24.
  41.  * 08-Mar-89: Added -nice, -mode and -display, built vector for life and hop.
  42.  * 24-Feb-89: Replaced hopalong display with life display from SunView1.
  43.  * 22-Feb-89: Added fix for color servers with n < 8 planes.
  44.  * 16-Feb-89: Updated calling conventions for XCreateHsbColormap();
  45.  *          Added -count for number of iterations per color.
  46.  *          Fixed defaulting mechanism.
  47.  *          Ripped out VMS hacks.
  48.  *          Sent to expo for X11R3 contrib.
  49.  * 15-Feb-89: Changed default font to pellucida-sans-18.
  50.  * 20-Jan-89: Added -verbose and fixed usage message.
  51.  * 19-Jan-89: Fixed monochrome gc bug.
  52.  * 16-Dec-88: Added SunView style password prompting.
  53.  * 19-Sep-88: Changed -color to -mono. (default is color on color displays).
  54.  *          Added -saver option. (just do display... don't lock.)
  55.  * 31-Aug-88: Added -time option.
  56.  *          Removed code for fractals to separate file for modularity.
  57.  *          Added signal handler to restore host access.
  58.  *          Installs dynamic colormap with a Hue Ramp.
  59.  *          If grabs fail then exit.
  60.  *          Added VMS Hacks. (password 'iwiwuu').
  61.  *          Sent to expo for X11R2 contrib.
  62.  * 08-Jun-88: Fixed root password pointer problem and changed PASSLENGTH to 20.
  63.  * 20-May-88: Added -root to allow root to unlock.
  64.  * 12-Apr-88: Added root password override.
  65.  *          Added screen saver override.
  66.  *          Removed XGrabServer/XUngrabServer.
  67.  *          Added access control handling instead.
  68.  * 01-Apr-88: Added XGrabServer/XUngrabServer for more security.
  69.  * 30-Mar-88: Removed startup password requirement.
  70.  *          Removed cursor to avoid phosphor burn.
  71.  * 27-Mar-88: Rotate fractal by 45 degrees clockwise.
  72.  * 24-Mar-88: Added color support. [-color]
  73.  *          wrote the man page.
  74.  * 23-Mar-88: Added HOPALONG routines from Scientific American Sept. 86 p. 14.
  75.  *          added password requirement for invokation
  76.  *          removed option for command line password
  77.  *          added requirement for display to be "unix:0".
  78.  * 22-Mar-88: Recieved Walter Milliken's comp.windows.x posting.
  79.  *
  80.  * Contributors:
  81.  *  milliken@heron.bbn.com
  82.  *  karlton@wsl.dec.com
  83.  *  dana@thumper.bellcore.com
  84.  *  vesper@3d.dec.com
  85.  */
  86.  
  87. #include <stdio.h>
  88. #include <signal.h>
  89. #include <string.h>
  90. #include <pwd.h>
  91. #include <X11/Xos.h>
  92. #include <X11/Xlib.h>
  93. #include <X11/Xutil.h>
  94. #include <X11/cursorfont.h>
  95.  
  96. extern char *crypt();
  97. extern char *getenv();
  98. extern char *Sencompass();
  99. extern char *getpasswd();
  100.  
  101. typedef struct {
  102.     char       *cmdline_arg;
  103.     int        (*lp_reinit) ();
  104.     void    (*lp_callback) ();
  105.     void    (*lp_init) ();
  106. }        lockProc;
  107.  
  108. /*
  109.  * Declare external interface routines for supported screen savers.
  110.  */
  111.  
  112. extern void randomInithop();
  113. extern int  hopdone();
  114. extern void hop();
  115.  
  116. extern void initlife();
  117. extern int  lifedone();
  118. extern void drawlife();
  119.  
  120. extern void initqix();
  121. extern int  qixdone();
  122. extern void drawqix();
  123.  
  124. lockProc    LockProcs[] = {
  125.     {"hop", hopdone, hop, randomInithop},
  126.     {"life", lifedone, drawlife, initlife},
  127.     {"qix", qixdone, drawqix, initqix}
  128. /*
  129.  * New screen savers may be added here.
  130.  * Refer to qix.c for simple sample screen saver.
  131.  */
  132.  
  133. };
  134. #define NUMPROCS (sizeof(LockProcs) / sizeof(lockProc))
  135.  
  136. int        (*reinit) () = NULL;
  137. void        (*callback) () = NULL;
  138. void        (*init) () = NULL;
  139. int        nosavers = False;    /* Do a screen saver? */
  140.  
  141. char       *pname;        /* argv[0] */
  142. Display       *dsp = NULL;        /* server display connection */
  143. int        screen;        /* current screen */
  144. Window        w,            /* window used to cover screen */
  145.         icon,        /* window used during password typein */
  146.         root;        /* convenience pointer to the root window */
  147. GC        gc,            /* main graphics drawing graphics context */
  148.         textgc;        /* graphics context used for text rendering */
  149. XColor        black,        /* used for text rendering */
  150.         white;        /* background of text screen */
  151. Colormap    cmap;        /* colormap */
  152. Cursor        mycursor;        /* blank cursor */
  153. Pixmap        lockc,
  154.         lockm;        /* pixmaps for cursor and mask */
  155. char        no_bits[] = {0};    /* dummy array for the blank cursor */
  156. int        passx,        /* position of the ?'s */
  157.         passy;
  158. XFontStruct *font;
  159. char       *fontname = NULL;    /* the font used in the password screen */
  160. int        inittime = -1;    /* time to iterate before calling init */
  161. int        skipRoot;        /* skip root password check */
  162. int        color;        /* color or mono */
  163. int        count = -1;        /* number of pixels to draw in each color */
  164. int        nicelevel = -1;    /* system priority at which to run process */
  165. int        lock;        /* locked or just screensaver mode */
  166. int        verbose = False;    /* print configuration info to stderr? */
  167. char       *display = NULL;    /* X display variable */
  168. int        timeout,
  169.         interval,
  170.         blanking,
  171.         exposures;        /* screen saver parameters */
  172.  
  173. #define ICONX            300
  174. #define ICONY            150
  175. #define ICONW            64
  176. #define ICONH            64
  177. #define ICONLOOPS        600
  178. #define DEFAULT_FONTNAME    "LucidaSans-12"
  179. #define BACKUP_FONTNAME        "fixed"
  180. #define DEFAULT_INITTIME    60
  181. #define DEFAULT_SKIPROOT    True
  182. #define DEFAULT_COUNT        100
  183. #define DEFAULT_NICE        10
  184. #define DEFAULT_DISPLAY        ":0"
  185.  
  186. /* VARARGS1 */
  187. void
  188. error(s1, s2)
  189.     char       *s1,
  190.            *s2;
  191. {
  192.     fprintf(stderr, s1, pname, s2);
  193.     exit(1);
  194. }
  195.  
  196.  
  197. void
  198. block()
  199. {
  200. }
  201.  
  202. void
  203. unblock()
  204. {
  205. }
  206.  
  207. void
  208. allowsig()
  209. {
  210.     unblock();
  211.     block();
  212. }
  213.  
  214.  
  215. XHostAddress *XHosts;
  216. int        HostAccessCount;
  217. Bool        HostAccessState;
  218.  
  219. void
  220. XGrabHosts(dsp)
  221.     Display    *dsp;
  222. {
  223.     XHosts = XListHosts(dsp, &HostAccessCount, &HostAccessState);
  224.     XRemoveHosts(dsp, XHosts, HostAccessCount);
  225.     XEnableAccessControl(dsp);
  226. }
  227.  
  228. void
  229. XUngrabHosts(dsp)
  230.     Display    *dsp;
  231. {
  232.     XAddHosts(dsp, XHosts, HostAccessCount);
  233.     XFree(XHosts);
  234.     if (HostAccessState == False)
  235.     XDisableAccessControl(dsp);
  236. }
  237.  
  238.  
  239. void
  240. GrabKeyboardAndMouse()
  241. {
  242.     Status    status;
  243.  
  244.     status = XGrabKeyboard(dsp, w, True,
  245.                GrabModeAsync, GrabModeAsync, CurrentTime);
  246.     if (status != GrabSuccess)
  247.     error("%s: couldn't grab keyboard! (%d)\n", status);
  248.     status = XGrabPointer(dsp, w, True, -1,
  249.               GrabModeAsync, GrabModeAsync, None, mycursor,
  250.               CurrentTime);
  251.     if (status != GrabSuccess)
  252.     error("%s: couldn't grab pointer! (%d)\n", status);
  253. }
  254.  
  255.  
  256. void
  257. XChangeGrabbedCursor(cursor)
  258.     Cursor    cursor;
  259. {
  260.     XGrabPointer(dsp, w, True, -1,
  261.          GrabModeAsync, GrabModeAsync, None, cursor, CurrentTime);
  262. }
  263.  
  264. void
  265. finish()
  266. {
  267.     XSync(dsp, 0);
  268.     XUngrabHosts(dsp);
  269.     XUngrabPointer(dsp, CurrentTime);
  270.     XUngrabKeyboard(dsp, CurrentTime);
  271.     XSetScreenSaver(dsp, timeout, interval, blanking, exposures);
  272.     XDestroyWindow(dsp, w);
  273.     if (color)
  274.     XUninstallColormap(dsp, cmap);
  275.     XFlush(dsp);
  276.     XCloseDisplay(dsp);
  277. }
  278.  
  279. void
  280. sigcatch()
  281. {
  282.     finish();
  283.     error("%s: caught terminate signal.\nAccess control list restored.\n");
  284. }
  285.  
  286. int
  287. ReadXString(s, slen)
  288.     char       *s;
  289.     int        slen;
  290. {
  291.     XEvent    event;
  292.     char    keystr[20];
  293.     char    c;
  294.     int        i,
  295.         bp,
  296.         len,
  297.         loops;
  298.     char       *pwbuf = (char *) malloc(slen);
  299.  
  300.     XSetForeground(dsp, gc, BlackPixel(dsp, screen));
  301.     init(dsp, icon, gc, color, inittime, count);
  302.     bp = 0;
  303.     while (True) {
  304.     loops = 0;
  305.     while (!XPending(dsp)) {
  306.         allowsig();
  307.         if (nosavers)
  308.         usleep(50000);
  309.         else
  310.         callback();
  311.         if (reinit())
  312.         init(dsp, icon, gc, color, inittime, count);
  313.         if (++loops >= ICONLOOPS) {
  314.         free(pwbuf);
  315.         return 1;
  316.         }
  317.     }
  318.     XNextEvent(dsp, &event);
  319.     switch (event.type) {
  320.     case KeyPress:
  321.         len = XLookupString((XKeyEvent *) & event, keystr, 20, NULL, NULL);
  322.         for (i = 0; i < len; i++) {
  323.         c = keystr[i];
  324.         switch (c) {
  325.         case 8:    /* ^H */
  326.         case 127:    /* DEL */
  327.             if (bp > 0)
  328.             bp--;
  329.             break;
  330.         case 10:    /* ^J */
  331.         case 13:    /* ^M */
  332.             s[bp] = '\0';
  333.             free(pwbuf);
  334.             return 0;
  335.         case 21:    /* ^U */
  336.             bp = 0;
  337.             break;
  338.         default:
  339.             s[bp] = c;
  340.             if (bp < slen - 1)
  341.             bp++;
  342.         }
  343.         }
  344.         memset(pwbuf, '?', slen);
  345.         XSetForeground(dsp, gc, white.pixel);
  346.         XFillRectangle(dsp, w, gc, passx, passy - font->ascent,
  347.                XTextWidth(font, pwbuf, slen),
  348.                font->ascent + font->descent);
  349.         XDrawString(dsp, w, textgc, passx, passy, pwbuf, bp);
  350.         break;
  351.  
  352.     case ButtonPress:
  353.         if (((XButtonEvent *) & event)->window == icon) {
  354.         free(pwbuf);
  355.         return 1;
  356.         }
  357.         break;
  358.  
  359.     case KeyRelease:
  360.     case ButtonRelease:
  361.     case MotionNotify:
  362.         break;
  363.  
  364.     default:
  365.         fprintf(stderr, "%s: unexpected event: %d\n", pname, event.type);
  366.         break;
  367.     }
  368.     }
  369. }
  370.  
  371. int
  372. getPassword()
  373. {
  374. #define PASSLENGTH 20
  375.     char    buffer[PASSLENGTH];
  376.     char    encrypted[PASSLENGTH];
  377.     XWindowAttributes xgwa;
  378.     char       *user = getenv("USER");
  379.     char       *passfile = getenv("ETC_PASSWD");
  380.     char       *name = "Name: ";
  381.     char       *pass = "Password: ";
  382.     char       *info = "Enter password to unlock; select icon to lock.";
  383.     char       *validate = "Validating login...";
  384.     char       *invalid = "Invalid login.";
  385.     int        y,
  386.         left,
  387.         nouser=0,
  388.         done;
  389.  
  390.     if (!user)
  391.     {
  392.     user = "UNKNOWN: Set the USER environment variable!";
  393.     nouser=1;
  394.     }
  395.  
  396.     XGetWindowAttributes(dsp, w, &xgwa);
  397.  
  398.     XChangeGrabbedCursor(XCreateFontCursor(dsp, XC_left_ptr));
  399.  
  400.     XSetForeground(dsp, gc, WhitePixel(dsp, screen));
  401.     XFillRectangle(dsp, w, gc, 0, 0, xgwa.width, xgwa.height);
  402.  
  403.     XMapWindow(dsp, icon);
  404.     XRaiseWindow(dsp, icon);
  405.  
  406.     left = ICONX + ICONW + font->max_bounds.width;
  407.     y = ICONY + font->ascent;
  408.  
  409.     XDrawString(dsp, w, textgc, left, y, name, strlen(name));
  410.     XDrawString(dsp, w, textgc, left + 1, y, name, strlen(name));
  411.     XDrawString(dsp, w, textgc,
  412.         left + XTextWidth(font, name, strlen(name)), y,
  413.         user, strlen(user));
  414.  
  415.     y += font->ascent + font->descent + 2;
  416.     XDrawString(dsp, w, textgc, left, y, pass, strlen(pass));
  417.     XDrawString(dsp, w, textgc, left + 1, y, pass, strlen(pass));
  418.  
  419.     passx = left + 1 + XTextWidth(font, pass, strlen(pass))
  420.     + XTextWidth(font, " ", 1);
  421.     passy = y;
  422.  
  423.     y = ICONY + ICONH + font->ascent + 2;
  424.     XDrawString(dsp, w, textgc, ICONX, y, info, strlen(info));
  425.  
  426.     XFlush(dsp);
  427.  
  428.     y += font->ascent + font->descent + 2;
  429.  
  430.     done = False;
  431.     while (!done) {
  432.  
  433.     if (ReadXString(buffer, PASSLENGTH)) {
  434.         XChangeGrabbedCursor(mycursor);
  435.         XUnmapWindow(dsp, icon);
  436.         XSetForeground(dsp, gc, WhitePixel(dsp, screen));
  437.         return 1;
  438.     }
  439.     XSetForeground(dsp, gc, WhitePixel(dsp, screen));
  440.     XFillRectangle(dsp, w, gc, ICONX, y - font->ascent,
  441.                XTextWidth(font, validate, strlen(validate)),
  442.                font->ascent + font->descent + 2);
  443.  
  444.     XDrawString(dsp, w, textgc, ICONX, y, validate, strlen(validate));
  445.  
  446.     if (!nouser)
  447.         {
  448.         Sencompass(buffer,encrypted);
  449.         done = !(strcmp(encrypted,getpasswd(user,passfile)));
  450.         }
  451.     else
  452.         {
  453.         done = 1;
  454.         }
  455.  
  456.     if (!done) {
  457.         XFlush(dsp);
  458.         sleep(1);
  459.         XFillRectangle(dsp, w, gc, ICONX, y - font->ascent,
  460.                XTextWidth(font, validate, strlen(validate)),
  461.                font->ascent + font->descent + 2);
  462.  
  463.         XDrawString(dsp, w, textgc, ICONX, y, invalid, strlen(invalid));
  464.     }
  465.     }
  466.     return 0;
  467. }
  468.  
  469. void
  470. justDisplay()
  471. {
  472.     XEvent    event;
  473.  
  474.     init(dsp, w, gc, color, inittime, count);
  475.     do {
  476.     while (!XPending(dsp)) {
  477.         callback();
  478.         if (reinit())
  479.         init(dsp, w, gc, color, inittime, count);
  480.     }
  481.     XNextEvent(dsp, &event);
  482.     } while (event.type != ButtonPress && event.type != KeyPress);
  483. }
  484.  
  485. void
  486. lockDisplay()
  487. {
  488.     XEvent    event;
  489.  
  490.     do {
  491.     if (nosavers) {
  492.         init(dsp, w, gc, color, inittime, count);
  493.         do {
  494.             while (!XPending(dsp));
  495.  
  496.             XNextEvent(dsp, &event);
  497.         } while (event.type != ButtonPress && event.type != KeyPress);
  498.     }
  499.     else {
  500.         justDisplay();
  501.     }
  502.     } while (getPassword());
  503. }
  504.  
  505. void
  506. usage(s)
  507.     char       *s;
  508. {
  509.     int        i;
  510.  
  511.     fprintf(stderr, "%s\nusage: %s [-display dsp] [-mode %s",
  512.         s, pname, LockProcs[0].cmdline_arg);
  513.     for (i = 1; i < NUMPROCS; i++)
  514.     fprintf(stderr, " | %s", LockProcs[i].cmdline_arg);
  515.     fprintf(stderr, "]\n");
  516.     fprintf(stderr, "\t%s %s\n",
  517.         "[-time n] [-count n] [-nice n]",
  518.         "[-font f] [-mono] [-saver] [-root] [-v]");
  519.     exit(1);
  520. }
  521.  
  522. void
  523. BuildPointersFromString(s)
  524.     char       *s;
  525. {
  526.     int        i;
  527.  
  528.     for (i = 0; i < NUMPROCS; i++) {
  529.     if (!strncmp(LockProcs[i].cmdline_arg, s, strlen(s))) {
  530.         reinit = LockProcs[i].lp_reinit;
  531.         callback = LockProcs[i].lp_callback;
  532.         init = LockProcs[i].lp_init;
  533.         nosavers = False;
  534.         if (verbose)
  535.         fprintf(stderr, "Mode: %s\n", s);
  536.         return;
  537.     }
  538.     }
  539.     usage("Unknown Mode.");
  540. }
  541.  
  542. main(argc, argv)
  543.     int        argc;
  544.     char       *argv[];
  545. {
  546.     XSetWindowAttributes xswa;
  547.     XGCValues    xgcv;
  548.     int        i;
  549.     char       *s;
  550.     int        n;
  551.  
  552.     pname = argv[0];
  553.     color = True;
  554.     lock = True;
  555.     skipRoot = -1;
  556.  
  557.     for (i = 1; i < argc; i++) {
  558.     s = argv[i];
  559.     n = strlen(s);
  560.     if (!strncmp("-display", s, n)) {
  561.         if (++i >= argc)
  562.         usage(s);
  563.         display = argv[i];
  564.     } else if (!strncmp("-mono", s, n)) {
  565.         color = False;
  566.     } else if (!strncmp("-saver", s, n)) {
  567.         lock = False;
  568.     } else if (!strncmp("-root", s, n)) {
  569.         skipRoot = False;
  570.     } else if (!strncmp("-verbose", s, n)) {
  571.         verbose = True;
  572.     } else if (!strncmp("-time", s, n)) {
  573.         if (++i >= argc)
  574.         usage(s);
  575.         inittime = atoi(argv[i]);
  576.         if (inittime < 1)
  577.         usage("-time argument must be positive.");
  578.     } else if (!strncmp("-count", s, n)) {
  579.         if (++i >= argc)
  580.         usage(s);
  581.         count = atoi(argv[i]);
  582.         if (count < 1)
  583.         usage("-count argument must be positive.\n");
  584.     } else if (!strncmp("-nice", s, n)) {
  585.         if (++i >= argc)
  586.         usage(s);
  587.         nicelevel = atoi(argv[i]);
  588.     } else if (!strncmp("-font", s, n)) {
  589.         if (++i >= argc)
  590.         usage(s);
  591.         fontname = argv[i];
  592.     } else if (!strncmp("-mode", s, n)) {
  593.         if (++i >= argc)
  594.         usage(s);
  595.         BuildPointersFromString(argv[i]);
  596.     } else {
  597.         fprintf(stderr, "Bad switch: ");
  598.         usage(s);
  599.     }
  600.     }
  601.  
  602.     if (display == NULL)
  603.     display = getenv("DISPLAY");
  604.  
  605.     if (display != NULL) {
  606.     char       *colon = strchr(display, ':');
  607.     int        n = colon - display;
  608.  
  609.     if (colon == NULL)
  610.         error("%s: Malformed -display argument, \"%s\"\n", display);
  611.  
  612. /*
  613.     if (n) {
  614.         if (strncmp(display, "unix", n)
  615.             && strncmp(display, "localhost", n))
  616.         error("%s: can't lock %s's display\n", strtok(display, ":"));
  617.     }
  618. */
  619.     } else
  620.     display = DEFAULT_DISPLAY;
  621.  
  622.     if (lock) {
  623.     block();
  624.     signal(SIGINT, sigcatch);
  625.     signal(SIGQUIT, sigcatch);
  626.     signal(SIGSEGV, sigcatch);
  627.     }
  628.     if (!(dsp = XOpenDisplay(display)))
  629.     error("%s: unable to open display %s.\n", display);
  630.  
  631.     if (fontname == NULL)
  632.     fontname = XGetDefault(dsp, pname, "font");
  633.     if (fontname == NULL)
  634.     fontname = DEFAULT_FONTNAME;
  635.  
  636.     if (count == -1) {
  637.     s = XGetDefault(dsp, pname, "count");
  638.     if (s != NULL)
  639.         count = atoi(s);
  640.     else
  641.         count = DEFAULT_COUNT;
  642.     }
  643.     if (nicelevel == -1) {
  644.     s = XGetDefault(dsp, pname, "nice");
  645.     if (s != NULL)
  646.         nicelevel = atoi(s);
  647.     else
  648.         nicelevel = DEFAULT_NICE;
  649.     }
  650.     if (inittime == -1) {
  651.     s = XGetDefault(dsp, pname, "time");
  652.     if (s != NULL)
  653.         inittime = atoi(s);
  654.     else
  655.         inittime = DEFAULT_INITTIME;
  656.     }
  657.     if (init == NULL) {
  658.     s = XGetDefault(dsp, pname, "mode");
  659.     if (s != NULL) {
  660.         BuildPointersFromString(s);
  661.     } else {
  662.         reinit = LockProcs[0].lp_reinit;
  663.         callback = LockProcs[0].lp_callback;
  664.         init = LockProcs[0].lp_init;
  665.         if (verbose)
  666.         fprintf(stderr, "Mode: %s\n", LockProcs[0].cmdline_arg);
  667.     }
  668.     }
  669.     if (skipRoot == -1) {
  670.     s = XGetDefault(dsp, pname, "root");
  671.     if (s != NULL)
  672.         skipRoot = !(strncmp("on", s, strlen(s)) == 0);
  673.     else
  674.         skipRoot = DEFAULT_SKIPROOT;
  675.     }
  676.     if (verbose) {
  677.     fprintf(stderr,
  678.         "%s: Font: %s, Time: %d, Root: %s, Nice: %d\n", pname,
  679.         fontname, inittime, skipRoot ? "False" : "True", nicelevel);
  680.     }
  681.     font = XLoadQueryFont(dsp, fontname);
  682.     if (font == NULL) {
  683.     fprintf(stderr, "%s: can't find font: %s, using %s...\n",
  684.         pname, fontname, BACKUP_FONTNAME);
  685.     font = XLoadQueryFont(dsp, BACKUP_FONTNAME);
  686.     if (font == NULL)
  687.         error("%s: can't even find %s!!!\n", BACKUP_FONTNAME);
  688.     }
  689.     screen = DefaultScreen(dsp);
  690.     if (color)
  691.     color = (DisplayCells(dsp, screen) > 2);
  692.     root = RootWindow(dsp, screen);
  693.  
  694.     if (color) {
  695.     if (XCreateHSBColormap(dsp, screen, &cmap, DisplayCells(dsp, screen),
  696.                    0.0, 1.0, 1.0, 1.0, 1.0, 1.0, True) == Success)
  697.         XInstallColormap(dsp, cmap);
  698.     else
  699.         error("%s: couldn't create colormap.");
  700.     } else
  701.     cmap = DefaultColormap(dsp, screen);
  702.  
  703.     black.pixel = BlackPixel(dsp, screen);
  704.     XQueryColor(dsp, cmap, &black);
  705.  
  706.     white.pixel = WhitePixel(dsp, screen);
  707.     XQueryColor(dsp, cmap, &white);
  708.  
  709.     lockc = XCreateBitmapFromData(dsp, root, no_bits, 1, 1);
  710.     lockm = XCreateBitmapFromData(dsp, root, no_bits, 1, 1);
  711.     mycursor = XCreatePixmapCursor(dsp, lockc, lockm, &black, &black, 0, 0);
  712.     XFreePixmap(dsp, lockc);
  713.     XFreePixmap(dsp, lockm);
  714.  
  715.     xswa.cursor = mycursor;
  716.     xswa.override_redirect = True;
  717.     xswa.background_pixel = black.pixel;
  718.     xswa.event_mask = KeyPressMask | ButtonPressMask;
  719.  
  720.     w = XCreateWindow(dsp, root,
  721.               0, 0,
  722.               DisplayWidth(dsp, screen),
  723.               DisplayHeight(dsp, screen),
  724.               0, CopyFromParent, InputOutput, CopyFromParent,
  725.               CWCursor | CWOverrideRedirect |
  726.               CWBackPixel | CWEventMask, &xswa);
  727.  
  728.     xswa.cursor = XCreateFontCursor(dsp, XC_target);
  729.     xswa.background_pixel = white.pixel;
  730.     xswa.event_mask = ButtonPressMask;
  731.  
  732.     icon = XCreateWindow(dsp, w,
  733.              ICONX, ICONY,
  734.              ICONW, ICONH,
  735.              1, CopyFromParent, InputOutput, CopyFromParent,
  736.              CWCursor | CWBackPixel | CWEventMask, &xswa);
  737.  
  738.     XMapWindow(dsp, w);
  739.     XRaiseWindow(dsp, w);
  740.  
  741.     xgcv.foreground = white.pixel;
  742.     xgcv.background = black.pixel;
  743.     gc = XCreateGC(dsp, w, GCForeground | GCBackground, &xgcv);
  744.  
  745.     xgcv.foreground = black.pixel;
  746.     xgcv.background = white.pixel;
  747.     xgcv.font = font->fid;
  748.     textgc = XCreateGC(dsp, w, GCFont | GCForeground | GCBackground, &xgcv);
  749.  
  750.     XGetScreenSaver(dsp, &timeout, &interval, &blanking, &exposures);
  751.     XSetScreenSaver(dsp, 0, 0, 0, 0);    /* disable screen saver */
  752.     GrabKeyboardAndMouse();
  753.  
  754.     if (lock) {
  755.     XGrabHosts(dsp);
  756.     allowsig();
  757.     }
  758.     srandom(getpid());
  759.  
  760.     if (lock)
  761.     lockDisplay();
  762.     else
  763.     justDisplay();
  764.  
  765.     finish();
  766.  
  767.     if (lock)
  768.     unblock();
  769.  
  770.     exit(0);
  771. }
  772.